/*
 * Copyright 2010 Francisco Modesto
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.googlecode.gwt.tinyaop.rebind;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.googlecode.gwt.tinyaop.client.WithInterceptor;
import com.googlecode.gwt.tinyaop.client.Interceptor;

public abstract class AbstractCreator {
  protected static final String SUFFIX = "__tiny_aop";

  protected JClassType classType;
  protected Class<? extends Annotation>[] annotations;

  public AbstractCreator(JClassType type, Class<? extends Annotation>[] annotations) {
    this.classType = type;
    this.annotations = annotations;
  }

  public abstract String create(TreeLogger logger, GeneratorContext context);

  protected Class<?>[] findInterceptors(JMethod method) {
    List<Class<?>> list = new ArrayList<Class<?>>();
    for (Class<? extends Annotation> annotation : annotations) {
      if (method.isAnnotationPresent(annotation)) {
        list.add(findInterceptors(method.getAnnotation(annotation)));
      }
    }
    return list.toArray(new Class<?>[list.size()]);
  }

  private Class<? extends Interceptor> findInterceptors(Annotation annotation) {
    return annotation.annotationType().getAnnotation(WithInterceptor.class).value();
  }

  protected String getGeneratedName() {
    return classType.getName().replace('.', '_') + SUFFIX;
  }
}
